package com.example.rabc.monitor;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;

/**
 * 性能监控切面，使用AOP实现方法性能监控
 */
@Aspect
@Component
public class PerformanceMonitorAspect {
    private final MonitorEventBus eventBus;
    
    public PerformanceMonitorAspect(MonitorEventBus eventBus) {
        this.eventBus = eventBus;
    }

    /**
     * 环绕通知，监控被@Monitored注解标记的方法性能
     * @param joinPoint 连接点，用于获取方法签名和执行方法
     * @return 方法执行结果
     * @throws Throwable 方法执行过程中抛出的异常
     */
    @Around("@annotation(com.example.rabc.monitor.Monitored)")
    public Object monitorPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis(); // 记录方法开始执行时间
        String methodName = joinPoint.getSignature().toShortString(); // 获取方法签名的短字符串表示
        
        try {
            Object result = joinPoint.proceed(); // 执行目标方法
            long executionTime = System.currentTimeMillis() - startTime; // 计算方法执行时间
            
            Map<String, Object> data = new HashMap<>();
            data.put("method", methodName);
            data.put("executionTime", executionTime);
            data.put("success", true);
            
            MonitorEvent event = new BaseMonitorEvent("METHOD_PERFORMANCE", data);
            eventBus.notifyObservers(event);  // 发布方法性能事件
            
            return result;
        } catch (Exception e) {
            // 记录异常信息
            long executionTime = System.currentTimeMillis() - startTime;
            
            Map<String, Object> data = new HashMap<>();
            data.put("method", methodName);
            data.put("executionTime", executionTime);
            data.put("success", false);
            data.put("exception", e.getClass().getSimpleName()); // 记录异常类型的简单名称
            data.put("message", e.getMessage()); // 记录异常消息
            
            MonitorEvent event = new BaseMonitorEvent("METHOD_PERFORMANCE", data);
            eventBus.notifyObservers(event);
            
            throw e;
        }
    }
}